package wiki.hitime.stl.daq.service.task;

import wiki.hitime.stl.daq.bean.bo.DataDbConfigBO;
import wiki.hitime.stl.daq.bean.db.DaqAcquisitionRule;
import wiki.hitime.stl.daq.manager.DaqAcquisitionDataRecordManager;
import wiki.hitime.stl.daq.manager.DaqAcquisitionRecordManager;
import wiki.hitime.stl.daq.manager.DaqAcquisitionRuleManager;
import wiki.hitime.stl.daq.manager.DaqDbConfigManager;
import wiki.hitime.stl.daq.service.factory.DataAcquisitionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;

/**
 * @author zhangdaoping
 * @create 2019-07-15 18:53
 */
@Service
@Slf4j
public class DataAcquisitionService {
    private DaqAcquisitionRuleManager daqAcquisitionRuleManager;
    private DaqDbConfigManager daqDbConfigManager;
    private DaqAcquisitionRecordManager daqAcquisitionRecordManager;
    private DaqAcquisitionDataRecordManager daqAcquisitionDataRecordManager;
    private DataCheckService dataCheckService;

    public DataAcquisitionService(DaqAcquisitionRuleManager daqAcquisitionRuleManager,
                                  DaqDbConfigManager daqDbConfigManager,
                                  DaqAcquisitionRecordManager daqAcquisitionRecordManager,
                                  DaqAcquisitionDataRecordManager daqAcquisitionDataRecordManager,
                                  DataCheckService dataCheckService) {
        this.daqAcquisitionRuleManager = daqAcquisitionRuleManager;
        this.daqDbConfigManager = daqDbConfigManager;
        this.daqAcquisitionRecordManager = daqAcquisitionRecordManager;
        this.daqAcquisitionDataRecordManager = daqAcquisitionDataRecordManager;
        this.dataCheckService = dataCheckService;
    }

    /**
     * 数据采集
     *
     * @param executeRuleId   执行规则id
     * @param executeRecordId 执行记录id
     */
    public void acquisitionData(Long executeRuleId, Long executeRecordId) {
        // 根据执行规则获取采集规则
        DaqAcquisitionRule acquisitionRule = daqAcquisitionRuleManager.getByExecuteRuleId(executeRuleId);
        Assert.notNull(acquisitionRule, "数据采集规则为空");
        // 根据采集规则获取数据源
        DataDbConfigBO dataDbConfigBO = daqDbConfigManager.loadDbConfig(acquisitionRule.getDbConfigId());
        Assert.notNull(dataDbConfigBO, "数据源配置信息为空");
        // 新增数据采集记录
        Long acquisitionRecordId = daqAcquisitionRecordManager.addNotProcessRecord(acquisitionRule, executeRecordId);
        Assert.notNull(acquisitionRecordId, "数据采集记录返回id为空");
        try {
            // 根据规则和数据源进行数据采集
            DataAcquisitionFactory acquisitionFactory = daqDbConfigManager.loadDbService(dataDbConfigBO.getDbTypeEnum());
            Assert.notNull(acquisitionFactory, "数据采集实现类为空");
            List<Object[]> dataList = acquisitionFactory.loadData(acquisitionRule.getAcquisitionExpression(), dataDbConfigBO);
            // 保存数据采集数据
            daqAcquisitionDataRecordManager.addDataRecord(acquisitionRecordId, dataList);
            // 更新数据采集记录状态
            daqAcquisitionRecordManager.updateProcessSucceed(acquisitionRecordId);
            // 执行数据检查
            dataCheckService.checkData(executeRecordId, acquisitionRule.getId(), acquisitionRecordId);
        } catch (Exception e) {
            log.error("采集数据出现异常，executeRecordId={}", executeRecordId, e);
            // 更新数据采集记录状态
            daqAcquisitionRecordManager.updateProcessFailed(acquisitionRecordId, e.getMessage());
        }
    }

}
